package server;

import server.Exceptions.AuthenticationConflictException;

import java.sql.SQLException;
import java.util.concurrent.LinkedBlockingQueue;

public class Server {
    private static final int PORT = 8888;
    private ClientsProcessor clientsProcessor;
    private LinkedBlockingQueue<Message> globalMessageQueue;
    private MessageBuffer messageBuffer;
    private ConnectionHandler connectionHandler;

    public Server() throws SQLException {
        DataBase.createTables();
        clientsProcessor = new ClientsProcessor();
        globalMessageQueue = new LinkedBlockingQueue<>();
        messageBuffer = new MessageBuffer();
    }

    public void start() {
        connectionHandler = new ConnectionHandler(PORT, this);
        initGlobalQueueProcessor();
        connectionHandler.start();
    }

    public void initGlobalQueueProcessor() {
        new Thread() {
            @Override
            public void run() {
                Message message;
                while (true) {
                    try {
                        message = globalMessageQueue.take();
                        DataBase.addMessage(message);
                        clientsProcessor.sendToAllClients(message);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

    boolean addClientToChat(String name, String password, Client client) throws AuthenticationConflictException {
        return clientsProcessor.addClientToChat(name, password, client);
    }

    boolean addNewClientToSystem(String name, String password) {
        return clientsProcessor.addNewClientToSystem(name, password);
    }

    boolean ifNameRegistered(String name) {
        return clientsProcessor.ifNameRegistered(name);
    }

    boolean ifCorrectPassword(String password){
        return clientsProcessor.ifCorrectPassword(password);
    }

    void removeClientFromChat(String name) {
        clientsProcessor.removeClientFromChat(name);
    }

    public void sendMessageToAll(Message outputMessage) {
        try {
            globalMessageQueue.put(outputMessage);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(Client client, String message) {
        client.sendMessage(message);
    }

    public MessageBuffer getMessageBuffer() {
        return messageBuffer;
    }
}
